home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / unix / mp14tar.z / mp14tar / mpack / dosos.c < prev    next >
C/C++ Source or Header  |  1994-06-01  |  6KB  |  265 lines

  1. /* (C) Copyright 1993 by John G. Myers
  2.  * All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without
  6.  * fee, provided that the above copyright notice appear in all copies
  7.  * and that both that copyright notice and this permission notice
  8.  * appear in supporting documentation, and that the name of John G.
  9.  * Myers not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  John G. Myers makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as
  13.  * is" without express or implied warranty.
  14.  *
  15.  * JOHN G. MYERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL JOHN G. MYERS BE LIABLE FOR ANY SPECIAL,
  18.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  19.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  21.  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <ctype.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #include <sys/types.h>
  29. #include "xmalloc.h"
  30. #include "common.h"
  31.  
  32. int overwrite_files = 0;
  33. int didchat;
  34.  
  35. /* The name of the file we're writing */
  36. static char *output_fname = 0;
  37.  
  38. /* Characters that can be in filenames */
  39. #define GOODCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
  40.  
  41. /* Generate a message-id */
  42. char *os_genid()
  43. {
  44.     static time_t curtime;
  45.     static char *hostname;
  46.     char *result;
  47.  
  48.     if (curtime == 0) {
  49.     time(&curtime);
  50.  
  51.     hostname = getenv("HOSTNAME");
  52.     if (!hostname) hostname="random-pc";
  53.     }
  54.  
  55.     result = xmalloc(25+strlen(hostname));
  56.     sprintf(result, "%lu@%s", curtime++, hostname);
  57.     return result;
  58. }
  59.  
  60. /* Create and return directory for a message-id */
  61. char *os_idtodir(id)
  62. char *id;
  63. {
  64.     static char buf[256];
  65.     int len = 0;
  66.     char *p;
  67.  
  68.     if (p = getenv("TMP")) {
  69.     p[200] = '\0';        /* Ensure sufficiently short */
  70.     strcpy(buf, p);
  71.     }
  72.     else {
  73.     strcpy(buf, "\\tmp");
  74.     (void)mkdir(buf);
  75.     }
  76.     strcat(buf, "\\parts");
  77.     (void)mkdir(buf);
  78.  
  79.     p = buf + strlen(buf);
  80.     *p++ = '\\';
  81.  
  82.     while (*id && len < 11) {
  83.     if (strchr(GOODCHARS, *id)) {
  84.         if (len++ == 8) *p++ = '.';
  85.         *p++ = *id;
  86.     }
  87.     id++;
  88.     }
  89.     *p = '\0';
  90.     if (mkdir(buf) == -1 && errno != EACCES) {
  91.     perror(buf);
  92.     return 0;
  93.     }
  94.     *p++ = '\\';
  95.     *p = '\0';
  96.     return buf;
  97. }
  98.  
  99. /*
  100.  * We are done with the directory returned by os_idtodir()
  101.  * Remove it
  102.  */
  103. os_donewithdir(dir)
  104. char *dir;
  105. {
  106.     char *p;
  107.  
  108.     /* Remove trailing slash */
  109.     p = dir + strlen(dir) - 1;
  110.     *p = '\0';
  111.  
  112.     rmdir(dir);
  113. }
  114.  
  115. /*
  116.  * Create a new file, with suggested filename "fname".
  117.  * "fname" may have come from an insecure source, so clean it up first.
  118.  * It may also be null.
  119.  * "contentType" is passed in for use by systems that have typed filesystems.
  120.  * "flags" contains a bit pattern describing attributes of the new file.
  121.  */
  122. FILE *os_newtypedfile(fname, contentType, flags)
  123. char *fname;
  124. char *contentType;
  125. int flags;
  126. {
  127.     char *p, *q;
  128.     int len, sawdot;
  129.     static int filesuffix=0;
  130.     char buf[128], *descfname=0;
  131.     FILE *outfile = 0;
  132.  
  133.     if (!fname) fname = "";
  134.  
  135.     /* Chop off any drive specifier, convert / to \ */
  136.     if (*fname && fname[1] == ':') fname +=2;
  137.     for (p = fname; *p; p++) if (*p == '/') *p = '\\';
  138.  
  139.     /* If absolute path name, chop to tail */
  140.     if (*fname == '\\') {
  141.     p = strrchr(fname, '\\');
  142.     fname = p+1;
  143.     }
  144.  
  145.     /* Clean out bad characters, create directories along path */
  146.     for (p=q=fname, len=sawdot=0; *p; p++) {
  147.     if (*p == '\\') {
  148.         if (!strncmp(p, "\\..\\", 4)) {
  149.         p[1] = p[2] = 'X';
  150.         }
  151.         *q = '\0';
  152.         (void) mkdir(fname);
  153.         *q++ = '\\';
  154.         len = sawdot = 0;
  155.     }
  156.     else if (*p == '.' && !sawdot) {
  157.         *q++ = '.';
  158.         sawdot++;
  159.         len = 0;
  160.     }
  161.     else if (len < (sawdot ? 3 : 8) && strchr(GOODCHARS, *p)) {
  162.         *q++ = *p;
  163.         len++;
  164.     }
  165.     }
  166.     *q = '\0';
  167.  
  168.     if (!fname[0]) {
  169.     do {
  170.         if (outfile) fclose(outfile);
  171.         sprintf(buf, "part%d", ++filesuffix);
  172.     } while (outfile = fopen(buf, "r"));
  173.     fname = buf;
  174.     }
  175.     else if (!overwrite_files && (outfile = fopen(fname, "r"))) {
  176.     /* chop off suffix */
  177.     p = strrchr(fname, '\\');
  178.     if (!p) p = fname;
  179.     p = strchr(p, '.');
  180.     if (*p) *p = '\0';
  181.  
  182.     /* append unique number */
  183.     do {
  184.         fclose(outfile);
  185.         sprintf(buf, "%s.%d", fname, ++filesuffix);
  186.      
  187.     } while (outfile = fopen(buf, "r"));
  188.     fname = buf;
  189.     }
  190.  
  191.     outfile = fopen(fname, (flags & FILE_BINARY) ? "wb" : "w");
  192.     if (!outfile) {
  193.     perror(fname);
  194.     }
  195.  
  196.     if (output_fname) free(output_fname);
  197.     output_fname = strsave(fname);
  198.  
  199.     if (strlen(fname) > sizeof(buf)-6) {
  200.     descfname = xmalloc(strlen(fname)+6);
  201.     }
  202.     else {
  203.     descfname = buf;
  204.     }
  205.     strcpy(descfname, fname);
  206.  
  207.     p = strrchr(descfname, '\\');
  208.     if (!p) p = descfname;
  209.     if (p = strrchr(p, '.')) *p = '\0';
  210.  
  211.     strcat(descfname, ".dsc");
  212.     (void) rename(TEMPFILENAME, descfname);
  213.     if (descfname != buf) free(descfname);
  214.     
  215.     fprintf(stdout, "%s (%s)\n", output_fname, contentType);
  216.     didchat = 1;
  217.  
  218.     return outfile;
  219. }
  220.  
  221. /*
  222.  * Close a file opened by os_newTypedFile()
  223.  */
  224. os_closetypedfile(outfile)
  225. FILE *outfile;
  226. {
  227.     fclose(outfile);
  228. }
  229.  
  230. /*
  231.  * (Don't) Handle a BinHex'ed file
  232.  */
  233. int
  234. os_binhex(infile, part, nparts)
  235. FILE *infile;
  236. int part;
  237. int nparts;
  238. {
  239.     return 1;
  240. }
  241.  
  242. /*
  243.  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
  244.  * did not match that supplied in the Content-MD5: header.
  245.  */
  246. os_warnMD5mismatch()
  247. {
  248.     char *warning;
  249.  
  250.     warning = xmalloc(strlen(output_fname) + 100);
  251.     sprintf(warning, "%s was corrupted in transit",
  252.         output_fname);
  253.     warn(warning);
  254.     free(warning);
  255. }
  256.  
  257. /*
  258.  * Report an error (in errno) concerning a filename
  259.  */
  260. os_perror(file)
  261. char *file;
  262. {
  263.     perror(file);
  264. }
  265.